/*
 * Ganesa Copyright (C) 2008 Wim Crols <twimpiex@gnx.be>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package be.gnx.ganesa.plugin.osm.command;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import be.gnx.ganesa.application.model.Application;
import be.gnx.ganesa.application.model.Feature;
import be.gnx.ganesa.application.model.Layer;
import be.gnx.ganesa.application.model.feature.Point;
import be.gnx.ganesa.application.plugin.ImportPlugin;
import be.gnx.ganesa.application.ui.dialog.ImportDialog.ImportDialogResult;
import be.gnx.ganesa.plugin.gpx.model.GPX;
import be.gnx.ganesa.plugin.osm.model.Node;
import be.gnx.ganesa.plugin.osm.model.OSM;
import be.gnx.ganesa.plugin.osm.model.Way;

public class ImportCommand extends be.gnx.ganesa.application.command.ImportCommand {

  public ImportCommand(Application application, ImportDialogResult importDialogResult, ImportPlugin importPlugin) {
    super(application, importDialogResult, importPlugin);
  }

  @Override
  protected void execute(Vector<Layer> layers) {
    for (Layer layer : layers) {
      if (layer instanceof GPX) {
        be.gnx.ganesa.plugin.gpx.command.ImportCommand gpxImportCommand = new be.gnx.ganesa.plugin.gpx.command.ImportCommand(application, importDialogResult,
            importPlugin);
        gpxImportCommand.execute(layers);
      }
      if (layer instanceof OSM) {
        final OSM osmLayer = (OSM) layer;
        try {
          URL url = new URL("http", "api.openstreetmap.org", 80, "/api/0.6/map?bbox="
              + Math.toDegrees(getBoundingBox().getBottomLeftCoordinate().getLongitude()) + ","
              + Math.toDegrees(getBoundingBox().getBottomLeftCoordinate().getLatitude()) + ","
              + Math.toDegrees(getBoundingBox().getTopRightCoordinate().getLongitude()) + ","
              + Math.toDegrees(getBoundingBox().getTopRightCoordinate().getLatitude()));
          getProject().setZoomBox(getBoundingBox());
          HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
          urlConnection.setRequestMethod("GET");
          urlConnection.connect();
          InputStream inputStream = urlConnection.getInputStream();
          SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
          parser.parse(inputStream, new DefaultHandler() {
            private Node node = null;
            private Way way = null;

            @Override
            public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
              Boolean visible = null;
              String user = null;
              Date timestamp = null;
              if (attributes.getValue("visible") != null) {
                visible = Boolean.parseBoolean(attributes.getValue("visible"));
              }
              if (attributes.getValue("user") != null) {
                user = attributes.getValue("user");
              }
              if (attributes.getValue("timestamp") != null) {
                // timestamp = new
                // Date(Date.parse(attributes.getValue("timestamp")));
              }

              if (name.equals("node")) {
                node = osmLayer.createNewNode(Long.parseLong(attributes.getValue("id")), Math.toRadians(Double.parseDouble(attributes.getValue("lat"))), Math
                    .toRadians(Double.parseDouble(attributes.getValue("lon"))), 0);
                node.setVisible(visible);
                node.setUser(user);
                node.setTimestamp(timestamp);
              }
              if (name.equals("way")) {
                way = osmLayer.newWay(Long.parseLong(attributes.getValue("id")));
                way.setVisible(visible);
                way.setUser(user);
                way.setTimestamp(timestamp);
              }
              if (name.equals("nd")) {
                Long ref = Long.parseLong(attributes.getValue("ref"));
                Point refNode = osmLayer.getPoint(ref);
                if (way != null) {
                  way.addNode((Node) refNode);
                }
              }
              if (name.equals("tag")) {
                String key = attributes.getValue("k");
                String value = attributes.getValue("v");
                Feature data = null;
                if (node != null) {
                  data = node;
                }
                if (way != null) {
                  data = way;
                }
                if (data != null) {
                  data.addAttribute(key, value);
                }
              }
              super.startElement(uri, localName, name, attributes);
            }

            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
              if (qName.equals("node")) {
                node = null;
              }
              if (qName.equals("way")) {
                way = null;
              }
              if (qName.equals("nd")) {
              }
              if (qName.equals("tag")) {
              }
              super.endElement(uri, localName, qName);
            }

          });
          urlConnection.disconnect();
        } catch (MalformedURLException malformedURLException) {
          System.err.println(malformedURLException);
        } catch (IOException ioException) {
          System.err.println(ioException);
        } catch (ParserConfigurationException parserConfigurationException) {
          System.err.println(parserConfigurationException);
        } catch (SAXException saxException) {
          System.err.println(saxException);
        }
      }
    }
  }

  @Override
  public String displayString() {
    return "import from ..";
  }

}
